package dosgi.core;

import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ManagedService;
import org.osgi.util.tracker.ServiceTracker;

import dbconnector.service.IServiceRegisterManager;
import dosgi.core.hook.HooksManager;
import dosgi.core.tracker.DatabaseTrackerCustomizer;
import dosgi.core.tracker.RemoteInvokerTrackerCustomizer;
import dosgi.core.util.LogHelper;
import dosgi.distribution.remote.RemoteInvocationClient;
/**
 * Class that customizes the starting and stopping of a bundle.
 *  
 * @author Jaroslaw Janik
 */
public class Activator implements BundleActivator {

	private HooksManager hooksManager;
	private ServiceRegistration<?> hooksManagerRegistration;
	private ServiceTracker<?, ?> databaseTracker;
	private ServiceTracker<?, ?> remoteInvokerTracker;

	/**
	 * On start bundle sets up database tracker which wait for Database bundle to be active. 
	 * It also registers as service remote invoker which waits for remote method invocation requests.
	 */
	public void start(BundleContext bundleContext) throws Exception {
		LogHelper.initialize(bundleContext);
		
		registerHookManager(bundleContext);
		
		openTrackers(bundleContext);
	}

	/**
	 * On stop bundle closes database tracker.
	 */
	public void stop(BundleContext bundleContext) throws Exception {
		closeTrackers(bundleContext);
		
		unregisterHookManager(bundleContext);
	}
	
	private void registerHookManager(BundleContext bundleContext) {
		Dictionary<String, String> props = new Hashtable<String, String>();
		props.put(Constants.SERVICE_PID, HooksManager.class.getName());
		
		hooksManager = new HooksManager(bundleContext);
		hooksManagerRegistration = bundleContext.registerService(ManagedService.class.getName(), hooksManager, props);
	}
	
	private void unregisterHookManager(BundleContext bundleContext) {
		hooksManagerRegistration.unregister();
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void openTrackers(BundleContext bundleContext) {
		databaseTracker = new ServiceTracker(bundleContext, IServiceRegisterManager.class.getName(), new DatabaseTrackerCustomizer(hooksManager, bundleContext));
		remoteInvokerTracker = new ServiceTracker(bundleContext, RemoteInvocationClient.class.getName(), new RemoteInvokerTrackerCustomizer(hooksManager, bundleContext));
		
		databaseTracker.open();
		remoteInvokerTracker.open();
	}
	
	private void closeTrackers(BundleContext bundleContext) {
		databaseTracker.close();
		remoteInvokerTracker.close();
	}
}
